package com.zengchen.common.utils;

import com.alibaba.fastjson.JSON;
import okhttp3.*;
import okhttp3.FormBody.Builder;

import javax.net.ssl.*;
import java.io.IOException;
import java.security.Security;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;

public class OkhttpUtil {


    private static final MediaType JSON_TYPE = MediaType.parse("application/json; charset=utf-8");

    private static int connectTimeout = 10;

    private static  int readTimeout = 20;

    /**
     * 使用OkHttp发送post请求
     *
     * @param url            请求地址
     * @param params         提交参数（以json格式提交）
     * @param connectTimeout 连接超时时间（毫秒）
     * @param readTimeout    读取结果超时时间（毫秒）
     * @return 返回服务器响应信息，如果请求报错返回null
     */
    public static String httpJsonPost(String url, Map<String, String> params, int connectTimeout, int readTimeout) throws Exception {
        OkHttpClient client = getSslOkHttpClient(connectTimeout, readTimeout);
        RequestBody body = RequestBody.create(JSON_TYPE, JSON.toJSONString(params));
        Request request = new Request.Builder().url(url).post(body).build();
        Response response = client.newCall(request).execute();
        return response.body().string();
    }

    public static String postParam(String url, Map<String, String> param, int connectTimeout, int readTimeout) throws Exception {
        OkHttpClient client = getSslOkHttpClient(connectTimeout, readTimeout);

        Builder formBuider = new FormBody.Builder();
        for (Entry<String, String> e : param.entrySet()) {
            formBuider.add(e.getKey(), e.getValue());
        }
        FormBody formBody = formBuider.build();

        final Request request = new Request.Builder().url(url).post(formBody).build();
        Call call = client.newCall(request);
        Response response = call.execute();
        String body = response.body().string();
        return body;
    }


    public static String postJSON(String url, String json, int connectTimeout, int readTimeout) throws Exception {
        OkHttpClient client = getSslOkHttpClient(connectTimeout, readTimeout);

        RequestBody requestBody = RequestBody.create(JSON_TYPE, json);

        final Request request = new Request.Builder().url(url).post(requestBody).build();
        Call call = client.newCall(request);
        Response response = call.execute();
        String body = response.body().string();
        return body;
    }

    public static String postJSONHaveHead(String url, String json, Map<String, String> head, int connectTimeout, int readTimeout) throws Exception {
        OkHttpClient client = getSslOkHttpClient(connectTimeout, readTimeout);
        RequestBody requestBody = RequestBody.create(JSON_TYPE, json);

        final Request request = new Request.Builder().url(url).post(requestBody).headers(Headers.of(head)).build();

        Call call = client.newCall(request);
        Response response = call.execute();
        String body = response.body().string();
        return body;
    }


    public static String get(String url, Integer connectTimeoutSecond, Integer readTimeoutSecond) throws Exception {
        if(connectTimeoutSecond == null){
            connectTimeoutSecond = connectTimeout;
        }
        if(readTimeoutSecond == null){
            readTimeoutSecond = readTimeout;
        }
        OkHttpClient client = getSslOkHttpClient(connectTimeoutSecond, readTimeoutSecond);

        final Request request = new Request.Builder()
                .url(HttpUrl.parse(url)).get().build();
        Call call = client.newCall(request);
        Response response = call.execute();
        String body = response.body().string();
        return body;
    }

    public static void postAsync(String url, Map<String, String> param, int connectTimeout, int readTimeout) throws Exception {
        OkHttpClient client = getSslOkHttpClient(connectTimeout, readTimeout);

        Builder formBuider = new FormBody.Builder();
        for (Entry<String, String> e : param.entrySet()) {
            formBuider.add(e.getKey(), e.getValue());
        }
        FormBody formBody = formBuider.build();

        final Request request = new Request.Builder().url(url).post(formBody).build();
        Call call = client.newCall(request);

        call.enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String body = response.body().string();
            }
            @Override
            public void onFailure(Call call, IOException e) {

            }
        });

    }

    private static OkHttpClient getSslOkHttpClient(int connectTimeout, int readTimeout) throws Exception {
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, new TrustManager[]{truseAllManager}, null);
        SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
        OkHttpClient client = new OkHttpClient.Builder()
                .sslSocketFactory(sslSocketFactory, truseAllManager)
                .hostnameVerifier(new TrustAllHostnameVerifier())
                .readTimeout(readTimeout, TimeUnit.SECONDS)
                .connectTimeout(connectTimeout, TimeUnit.SECONDS)
                .build();
        return client;
    }


    private static class TrustAllHostnameVerifier implements HostnameVerifier {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }

    private static X509TrustManager truseAllManager = new X509TrustManager() {
        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
        }

        public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
        }

        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[]{};
        }
    };

}
